#!/usr/bin/env python
#-*- coding: utf-8 -*-
# AUTHOR: guangling.hou@gmail.com
# FILENAME: daemonize.py
# CREATED: 2014-03-11 14:10
# MODIFIED: 2014-04-03 19:33
# Description:

import sys,os,fcntl


class Daemon():
    def __init__(self,
            stdout='/dev/null',
            stdin='/dev/null',
            stderr='',
            pidfile = ''):
        self._stdin = stdin
        self._stdout = stdout
        self._stderr = stderr
        self._pidfile = pidfile
        self._stderr_file = None

    def run(self):
        if self._pidfile:
            if os.path.isfile(self._pidfile):
                print self._pidfile, ' is already exist'
                exit(1)
        try:
            pid = os.fork()
            if pid > 0:
                sys.exit(0)
        except OSError,e:
            sys.stderr.write('first fork error %s',str(e))

        os.setsid()
        os.chdir('/')
        os.umask(0)

        try:
            pid = os.fork()
            if pid > 0:
                sys.exit(0)
        except OSError,e:
            sys.stderr.write('second fork error %s',str(e))

        sys.stdout.flush()
        sys.stderr.flush()

        if not self._stderr:
            self._stderr = '/tmp/' + str(os.getpid()) + '.elog'

        si = file(self._stdin,'r')
        so = file(self._stdout,'a+')
        se = file(self._stderr,'a+',0)
        self._stderr_file = se
        os.dup2(si.fileno(),sys.stdin.fileno())
        os.dup2(so.fileno(),sys.stdout.fileno())
        os.dup2(se.fileno(),sys.stderr.fileno())

        #write pid
        if not self._pidfile:
            self._pidfile = '/tmp/' + str(os.getpid()) + '.pid'

        lockfile = open(self._pidfile, "w")
        fcntl.lockf(lockfile, fcntl.LOCK_EX | fcntl.LOCK_NB)
        lockfile.write("%s" % (os.getpid()))
        lockfile.flush()


    def exit(self):
        os.remove(self._pidfile)
        if self._stderr_file:
            self._stderr_file.close()
        sys.exit(0)



if __name__ == '__main__':
    daemon.run()
